package com.li.general.image
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;

public class PhotoLoader extends Sprite
{
    private var _loader:Loader;
    private var _fitFrame:Point;
    private var _loaderContext:LoaderContext;
    private var _useFitting:Boolean;
    private var _memScale:Number = 1;
    private var _bitmap:Bitmap;
    private var _holder:Sprite;

    public function PhotoLoader()
    {
        super();

        // Holder.
        _holder = new Sprite();
        addChild(_holder);

        // Loader.
        _loader = new Loader();
        _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteHandler);
        _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loaderProgressHandler);
        _loaderContext = new LoaderContext();
        _loaderContext.checkPolicyFile = true;
        _holder.addChild(_loader);

        // Over bitmap.
        _bitmap = new Bitmap();
        _holder.addChild(_bitmap);
    }

    public function loadPhoto(url:String):void
    {
        // Send loader to back.
        _holder.addChildAt(_loader, 0);

        // Start load.
        _loader.load(new URLRequest(url), _loaderContext);
    }

    public function setFitFrame(width:Number, height:Number):void
    {
        _fitFrame = new Point(width, height);
    }

    /*
        Enables proportional resizing of the image to fit
        a specific frame.
     */
    public function set useFitting(value:Boolean):void
    {
        _useFitting = value;

        if(_useFitting)
            _holder.scaleX = _holder.scaleY = _memScale;
        else
            _holder.scaleX = _holder.scaleY = 1;
    }
    public function get useFitting():Boolean
    {
        return _useFitting;
    }

    private function loaderProgressHandler(evt:ProgressEvent):void
    {
        dispatchEvent(evt);
    }

    private function loaderCompleteHandler(evt:Event):void
    {
        // Redraw.
        var bmd:BitmapData = new BitmapData(_loader.width, _loader.height, false, 0xFFFFFF);
        bmd.draw(_loader);
        _bitmap.bitmapData = bmd;

        // Send bitmap to back.
        _holder.addChildAt(_bitmap, 0);

        // Calculate fitting.
        if(_fitFrame)
        {
            _holder.scaleX = _holder.scaleY = 1;
            var photoWidth:Number = _loader.width;
            var photoHeight:Number = _loader.height;
            var horizontalRatio:Number = _fitFrame.x/photoWidth;
            var verticalRatio:Number = _fitFrame.y/photoHeight;
            horizontalRatio = horizontalRatio > 1 ? 1 : horizontalRatio;
            verticalRatio = verticalRatio > 1 ? 1 : verticalRatio;
            _memScale = Math.min(horizontalRatio, verticalRatio);

            if(_useFitting)
                _holder.scaleX = _holder.scaleY = _memScale;
        }
        
        // Notify.
        dispatchEvent(evt);
    }
}
}